package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Queue;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

/**
 * This class constitutes the GCOM Chat client GUI. It provides a simple text
 * area where group messages are displayed as well as a list of members of the
 * group. In addition to that it also accepts text input for sending own
 * messages to the group.
 * 
 */
public class GComChatGUI extends JFrame {

    private static final long serialVersionUID = 6489864523933644217L;
    private final JPanel contentPane;

    private JEditorPane m_output; // Where messages are printed
    private JScrollPane m_scrollOutput;
    private JList m_clientList;
    private JScrollPane m_scrollClientList;
    private JPanel m_sendPanel;
    private JTextField m_input; // Input for message to send
    private JButton m_sendBtn;
    private StringBuffer m_text; // Chat server
    private final Queue<String> outputQueue;
    private final String[] connectionData = new String[5];

    /**
     * Create the frame.
     */
    public GComChatGUI(final Queue<String> outputQueue) {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        this.setLocation(30, 30);
        setFocusable(true);
        this.setSize(640, 480);
        setMinimumSize(new Dimension(640, 480));

        this.outputQueue = outputQueue;

        createComponents();
        queryConnectionData();
        setTitle("GCom Chat Client - Nick: " + connectionData[1] + " - Group: "
                + connectionData[2]);
    }

    public String[] getConnectionData() {
        return connectionData;
    }

    private void queryConnectionData() {

        final JPanel p = new JPanel(new BorderLayout(5, 5));
        final JCheckBox chkbxM = new JCheckBox("Reliable Multicast");
        final JCheckBox chkbxO = new JCheckBox("Causal Ordering");

        final JPanel labels = new JPanel(new GridLayout(0, 1, 2, 2));
        labels.add(new JLabel("Nickname", SwingConstants.RIGHT));
        labels.add(new JLabel("Groupname", SwingConstants.RIGHT));
        labels.add(new JLabel("Nameservers(10.0.0.1,..)", SwingConstants.RIGHT));
        p.add(labels, BorderLayout.WEST);

        final JPanel controls = new JPanel(new GridLayout(0, 1, 2, 2));
        final JTextField nickField = new JTextField(10);
        final JTextField groupField = new JTextField(10);
        final JTextField nameField = new JTextField(10);

        controls.add(nickField);
        controls.add(groupField);
        controls.add(nameField);

        p.add(controls, BorderLayout.CENTER);
        final JPanel boxPanel = new JPanel();
        boxPanel.add(chkbxM);
        boxPanel.add(chkbxO);
        p.add(boxPanel, BorderLayout.SOUTH);

        // put any already stored values.
        nameField.setText(connectionData[0]);
        nickField.setText(connectionData[1]);
        groupField.setText(connectionData[2]);

        final int answer = JOptionPane.showConfirmDialog(contentPane, p,
                "Supply connection data.", JOptionPane.OK_CANCEL_OPTION);

        connectionData[0] = nameField.getText();
        connectionData[1] = nickField.getText();
        connectionData[2] = groupField.getText();
        connectionData[3] = "" + chkbxM.isSelected();
        connectionData[4] = "" + chkbxO.isSelected();
        switch (answer) {
        case 0:
            // if any of the fields are empty we rerun this dialog.
            if (connectionData[0].equals("") || connectionData[1].equals("")
                    || connectionData[2].equals("")) {
                queryConnectionData();
            }
            break;
        default:
            System.exit(0);
            break;
        }

    }

    private void createComponents() {

        m_output = new JEditorPane("text/html", "");
        m_scrollOutput = new JScrollPane(
                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        m_clientList = new JList();
        m_scrollClientList = new JScrollPane(
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        m_sendPanel = new JPanel(new BorderLayout());
        m_input = new JTextField();
        m_input.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent arg0) {
                inputTextAction();
            }
        });

        m_sendBtn = new JButton();
        m_text = new StringBuffer();

        m_sendBtn.setText("Send");
        m_sendBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent arg0) {
                inputTextAction();

            }
        });

        m_scrollClientList.setPreferredSize(new Dimension(200, 400));
        m_scrollClientList.getViewport().setView(m_clientList);

        m_output.setPreferredSize(new Dimension(300, 400));
        m_output.setEditable(false);
        m_output.setDisabledTextColor(Color.BLACK);
        m_output.setEnabled(false);
        m_scrollOutput.getViewport().setView(m_output);

        m_sendPanel.add(m_input, BorderLayout.CENTER);
        m_sendPanel.add(m_sendBtn, BorderLayout.EAST);

        contentPane.add(m_scrollClientList, BorderLayout.EAST);
        contentPane.add(m_scrollOutput, BorderLayout.CENTER);
        contentPane.add(m_sendPanel, BorderLayout.SOUTH);
    }

    private void inputTextAction() {
        final String input = m_input.getText();
        if (input != null && !input.equals("")) {
            outputQueue.offer(m_input.getText());
            m_input.setText("");
        }
    }

    /**
     * Print text to the chat output box.
     * 
     * @param strings
     *            - a string to be printed.
     */
    public void printChat(final String[] strings) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                m_text.append("<b>" + strings[0] + "</b>:" + strings[1]
                        + "<br>");
                m_output.setText("<html><head><title>Chat</title></head><body bgcolor=\"white\"><font face=arial size=4 color=\"black\">"
                        + m_text + "</font></body></html>");
            }
        });
    }

    public void errorPrompt(final String message, final boolean exit) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(contentPane, message, "Error",
                        JOptionPane.QUESTION_MESSAGE);
                if (exit) {
                    System.exit(1);
                }
            }
        });
    }

    public void setClientList(final Vector<String> clist) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (clist != null) {
                    m_clientList.setListData(clist);
                }
            }
        });
    }

}